import sys
import cv
from videoInput import videoInput

class handDetect:
	# pipeline
	colourCorrect = None
	skinDetect = None
	segment = None

	def __init__(self, skinDetector):
		self.skinDetect = skinDetector  

	def detect(self, image):
		tmpImage = cv.CreateImage( ( image.width, image.height ), image.depth, image.nChannels );
		cv.Copy( image, tmpImage, None );

		if self.colourCorrect:
			tmpImage = self.colourCorrect.correct(tmpImage)
 
		if self.skinDetect:
			tmpImage = self.skinDetect.detect(tmpImage)

		if self.segment:
			tmpImage = self.segment.segment(tmpImage)

		return tmpImage


class hsvSkinDetector:
	""" simple hsvSkinDetector """
	hsv_min = cv.Scalar(6, 0, 0, 0);
	hsv_max = cv.Scalar(38, 255, 255, 0);

	def __init__(self):
		pass	

	def detect(self, image):
		hsvImage = cv.CreateImage( ( image.width, image.height ), 8, image.nChannels );
		resultImage = cv.CreateImage( ( image.width, image.height ), 8, 1 );

		cv.CvtColor( image, hsvImage, cv.CV_BGR2HSV )
		cv.InRangeS( hsvImage, self.hsv_min, self.hsv_max, resultImage )
		return resultImage

class bgrSkinDetector:
	""" simple bgrSkinDetector """
	bgr_min = cv.Scalar(0, 30, 0, 0);
	bgr_max = cv.Scalar(50, 150, 255, 0);

	def __init__(self):
		pass	

	# Normalises but slow as pants
	def normalise(self, image):
		hsvImage = cv.CreateImage( ( image.width, image.height ), 8, 3 );
		resultImage = cv.CreateImage( ( image.width, image.height ), image.depth, 3 );
		h = cv.CreateImage(cv.GetSize(image), 8, 1);
		s = cv.CreateImage(cv.GetSize(image), 8, 1);
		v = cv.CreateImage(cv.GetSize(image), 8, 1);

		cv.CvtColor( image, hsvImage, cv.CV_BGR2HSV )
		cv.Split(hsvImage, h, s, v, None)
		cv.EqualizeHist(v, v)
		cv.Merge(h, s, v, None, hsvImage)
		cv.CvtColor(hsvImage, resultImage, cv.CV_HSV2BGR)
		return resultImage

	def detect(self, image):
		normImage = self.normalise(image)
		resultImage = cv.CreateImage( ( image.width, image.height ), 8, 1 );

		cv.InRangeS( normImage, self.bgr_min, self.bgr_max, resultImage )
		return resultImage


def on_mouse(event, x, y, button, pointer ):
	"""For later use in grabbing segments of images for training """
	if button > 0:
		print "mouse event %s, %s, %s, %s, %s" % (event, x, y, button, pointer)

### MAIN
if __name__ == '__main__':
	userIn = 0

	if len(sys.argv) > 1:
		if sys.argv[1].isdigit():
			userIn = int(sys.argv[1])
		else:
			userIn = sys.argv[1]

	cv.NamedWindow("camera", cv.CV_WINDOW_AUTOSIZE )
	cv.NamedWindow("segmented", cv.CV_WINDOW_AUTOSIZE)

	cv.SetMouseCallback( "camera", on_mouse, None )

	video = videoInput(userIn)
	
	skinDetector = hsvSkinDetector() 
	detector = handDetect(skinDetector)	

	paused = False

	while True:
		if not paused:
			img = video.frame
			detected = detector.detect(img)

		# Resize and display the video + processed video
		hsImage = cv.CreateImage( ( img.width/2, img.height/2 ), img.depth, img.nChannels );
		cv.Resize(img, hsImage)
		cv.ShowImage("camera", hsImage)

		hsImage = cv.CreateImage( ( detected.width/2, detected.height/2 ), 
			detected.depth, detected.nChannels );
		cv.Resize(detected, hsImage)
		cv.ShowImage("segmented", hsImage)

		key = cv.WaitKey(1000/1000)
		if key == 27: #escape
			break
		elif key == 32: #pause
			paused = not paused
			


